# -*- coding:utf-8 -*-
"""
序列化类
"""
__author__ = "shu2015626"

import time
import random
from rest_framework import serializers
from django.conf import settings

from goods.models import Goods
from .models import ShoppingCart, OrderInfo, OrderGoods
from goods.serializers import GoodsSerializer
from utils.alipay import AliPay


class ShoppingCartDetailSerializer(serializers.ModelSerializer):
    """
    购物车展示的时候使用
    """
    # 每个购物车对同一种商品只能有一个记录
    goods = GoodsSerializer(many=False)

    class Meta:
        model = ShoppingCart
        fields = "__all__"


# 继承Serializer是没有实现create和update方法的，需要自己实现
class ShoppingCartSerializer(serializers.Serializer):
    """
    购物车操作的时候使用
    """
    user = serializers.HiddenField(
        default=serializers.CurrentUserDefault()
    )
    nums = serializers.IntegerField(required=True, min_value=1, label="数量",
                                    error_messages={
                                        'min_value': "商品数量不能小于1",
                                        'required': "请选择购买数量"
                                    })
    # 传进来的必须是Goods这个模型的主键
    goods = serializers.PrimaryKeyRelatedField(queryset=Goods.objects.all(), required=True, label='商品')

    def create(self, validated_data):
        # 现在的request不是放到self里的，而是在上下文里.和viewsets里不同
        user = self.context['request'].user
        nums = validated_data['nums']
        goods = validated_data['goods']  # 因为设置的是外键，所以这里已经被取出为Goods的对象了

        existed = ShoppingCart.objects.filter(user=user, goods=goods)
        if existed:
            existed = existed[0]
            existed.nums += nums
            existed.save()
        else:
            existed = ShoppingCart.objects.create(**validated_data)

        return existed

    def update(self, instance, validated_data):
        # 修改商品数量
        instance.nums = validated_data['nums']
        instance.save()
        return instance


class OrderGoodsSerializer(serializers.ModelSerializer):
    goods = GoodsSerializer(many=False)

    class Meta:
        model = OrderGoods
        fields = "__all__"


class OrderDetailSerializer(serializers.ModelSerializer):
    goods = OrderGoodsSerializer(many=True)
    alipay_url = serializers.SerializerMethodField(read_only=True)  # 生成支付分url地址

    def get_alipay_url(self, obj):
        """
        alipay_url在数据model中没有对应的数据，是我们要在serializer中新增的内容，
        我们声明其为SerializerMethodField，就要为其创建一个函数，命名规则是get + '_' + field_name
        :param obj: 是这里serializer对象
        :return:
        """
        # 生成支付链接
        alipay = AliPay(
            appid=settings.ALI_APPID,
            app_notify_url=settings.ALI_APP_NOTIFY_URL,  # 异步的
            app_private_key_path=settings.PRIVATE_KEY_PATH,
            alipay_public_key_path=settings.ALI_PUB_KEY_PATH,  # 支付宝的公钥，验证支付宝回传消息使用，不是你自己的公钥,
            debug=settings.ALI_IS_DEBUG,  # 默认False,
            return_url=settings.ALI_RETURN_URL  # 同步的
        )

        data = alipay.direct_pay(
            subject=obj.order_sn,
            out_trade_no=obj.order_sn,
            total_amount=obj.order_mount,
            return_url=settings.ALI_RETURN_URL
        )
        alipay_url = "{getway}?{data}".format(getway=settings.ALI_GETWAY, data=data)

        return alipay_url

    class Meta:
        model = OrderInfo
        fields = "__all__"


class OrderSerializer(serializers.ModelSerializer):
    user = serializers.HiddenField(
        default=serializers.CurrentUserDefault()
    )
    trade_no = serializers.CharField(read_only=True)
    pay_status = serializers.CharField(read_only=True)
    order_sn = serializers.CharField(read_only=True)
    pay_time = serializers.DateTimeField(read_only=True, format="%Y-%m-%d %H:%M:%S")
    add_time = serializers.DateTimeField(read_only=True, format="%Y-%m-%d %H:%M:%S")
    alipay_url = serializers.SerializerMethodField(read_only=True)  # 生成支付url地址

    def get_alipay_url(self, obj):
        """
        alipay_url在数据model中没有对应的数据，是我们要在serializer中新增的内容，
        我们声明其为SerializerMethodField，就要为其创建一个函数，命名规则是get + '_' + field_name
        :param obj: 是这里serializer对象
        :return:
        """
        # 生成支付链接
        alipay = AliPay(
            appid=settings.ALI_APPID,
            app_notify_url=settings.ALI_APP_NOTIFY_URL,  # 异步的
            app_private_key_path=settings.PRIVATE_KEY_PATH,
            alipay_public_key_path=settings.ALI_PUB_KEY_PATH,  # 支付宝的公钥，验证支付宝回传消息使用，不是你自己的公钥,
            debug=settings.ALI_IS_DEBUG,  # 默认False,
            return_url=settings.ALI_RETURN_URL  # 同步的
        )

        data = alipay.direct_pay(
            subject=obj.order_sn,
            out_trade_no=obj.order_sn,
            total_amount=obj.order_mount,
            return_url=settings.ALI_RETURN_URL
        )
        alipay_url = "{getway}?{data}".format(getway=settings.ALI_GETWAY, data=data)

        return alipay_url

    def generate_order_sn(self):
        # 当前时间 + user_id + 随机数
        order_sn = f"{time.strftime('%Y%m%d%H%M%S')}{self.context['request'].user.id}{random.randint(10, 99)}"
        return order_sn

    def validate(self, attrs):
        attrs['order_sn'] = self.generate_order_sn()
        return attrs

    class Meta:
        model = OrderInfo
        fields = '__all__'


